﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Xml;
using System.Text.RegularExpressions;
using System.ZLib.Zip;
using System.PList;
using System.Web;
using System.Common;
namespace eDoc.BO
{
    public class UrlExtension
    {
        public static string UrlShema()
        {
            string urlScheme = HttpContext.Current.Request.Url.Scheme;
            //if(urlScheme.Contains("http"))
            //{
            //    urlScheme = urlScheme.Replace("http","https");
            //}
            string url = urlScheme+ "://" + HttpContext.Current.Request.Url.Host;
            //if (HttpContext.Current.Request.IsSecureConnection)
            //{
            //    url += ":" + HttpContext.Current.Request.Url.Port;
            //}

            if (HttpContext.Current.Request.Url.Port != 80 && HttpContext.Current.Request.Url.Port!=443)
            {
                url += ":" + HttpContext.Current.Request.Url.Port;
            }
            return url;
        }

        public static string UrlCurrent()
        {
            string result = HttpContext.Current.Request.Url.AbsoluteUri;
            return result;
        }

        public static string UrlReferrer()
        {
            string result = HttpContext.Current.Request.UrlReferrer.AbsoluteUri;
            return result;
        }
    }

    
    public class Common
    {
        
        public static string PartnerCode = System.Configuration.ConfigurationManager.AppSettings["PartnerCode"].ToString();
        public static string UrlInstall = UrlExtension.UrlShema(); //System.Configuration.ConfigurationManager.AppSettings["UrlInstall"].ToString();
        public static string folderUnrar = System.Configuration.ConfigurationManager.AppSettings["folderUnrar"].ToString();//"\\File\\FileUnrar\\";
        public static string folderPlist = System.Configuration.ConfigurationManager.AppSettings["folderPlist"].ToString();//"\\File\\FilePlist\\";
        public static string folderIPA = System.Configuration.ConfigurationManager.AppSettings["folderIPA"].ToString();//"\\File\\FileIPA\\";
        public static string folderInfo = System.Configuration.ConfigurationManager.AppSettings["folderInfo"].ToString();//"\\File\\FileInfo\\";
        public static bool CheckAuthen = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["CheckAuthen"]);

        const string key_CFBundleIdentifier = "<key>CFBundleIdentifier</key>";
        const string key_CFBundleVersion = "<key>CFBundleVersion</key>";
        const string key_CFBundleDisplayName = "<key>CFBundleDisplayName</key>";
        const string key_CFBundleName = "<key>CFBundleName</key>";
        const string key_MinimumOSVersion = "<key>MinimumOSVersion</key>";
        const string key_CFBundleSupportedPlatforms = "<key>CFBundleSupportedPlatforms</key>";
        const string key_CFBundleSignature = "<key>CFBundleSignature</key>";
        const string key_BuildTime = "<key>BuildTime</key>";
        const string key_ExpirationDate = "<key>ExpirationDate</key>";

        

        static string[] plistKey = new string[] 
                            {   "CFBundleIdentifier", "CFBundleVersion", "CFBundleDisplayName", "CFBundleName",
                                "MinimumOSVersion", "CFBundleSupportedPlatforms", "CFBundleSignature", "BuildTime",
                                "DTPlatformName", "DTPlatformVersion", "UIDeviceFamily"
                            };
        static string expirationDate = "ExpirationDate";
        public enum ERROR_CODE
        {
            SYNC_NO_ERROR = 0,
            SYNC_NETWORK_ERROR = 1,
            SYNC_LOGIN_ERROR = 2,
            SYNC_SERVER_LISTING_ERROR = 3,
            SYNC_DISKSPACE_NOT_ENOUGHT = 4,
            SYNC_USER_CANCELLED = 5,
            SYNC_USER_WIFI_ONLY_BUT_NOT_AVAILABLE = 6,
            SYNC_SERVER_NOT_AVAILABLE = 7,
            SYNC_DEVICE_NOT_ACTIVATED = 8,
            SYNC_DEVICE_DISABLED_BY_ADMIN = 9,
            SYNC_UNKNOWN_ERROR = 10
        }
        public class Plist
        {

            private static string ReturnStringArray(string input)
            {
                string value = "";
                if (input.Trim() != "")
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(input);

                    XmlNodeList nodeList = doc.SelectNodes("//string");


                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        if (i < nodeList.Count - 1)
                        {
                            value += nodeList[i].InnerText + ",";
                        }
                        else
                            value += nodeList[i].InnerText;
                    }
                }

                return value;

            }

            private static string ReturnTextBetweenArray(string input)
            {
             
                Regex regex = new Regex(@"<array>(.*?)</array>");

                Match match = regex.Match(input);
                string result = "";
                
                if (match.Success)
                {
                    result = match.Groups[1].Value;
                    result = ReturnTextBetweenString(result);
                }
                
                
                return result;
            }
            private static string ReturnTextBetweenString(string input)
            {
                
                Regex regex = new Regex(@"<string>(.*?)</string>");

                Match match = regex.Match(input);
                string result = "";
                if (match.Success)
                {
                    result = match.Groups[1].Value;
                   
                }
                return result;
            }

            /// <summary>
            ///  Tra ve file info.plist trong ipa
            /// </summary>
            /// <param name="ZipFileName"></param>
            /// <returns></returns>
            public static string PathFileInfoPlist(string ZipFileName)
            {

                System.ZLib.Zip.ZipFile zipFile = new System.ZLib.Zip.ZipFile(ZipFileName);

                string path = "";
                string zipName = "";
                for (int i = 0; i < zipFile.Count; i++)
                {
                    zipName = zipFile[i].Name.ToLower();

                    if (zipName.IndexOf(@"info.plist") > 0)
                    {
                        path = zipFile[i].Name.Replace("/", "\\");// +"info.plist";
                        break;
                    }
                }


                return path;
            }

            /// <summary>
            /// Luu lai file info.plist sau khi da doc dc trong file ipa. Gia tri tra ve la duong dan cua file info.plist da dc giai ma.
            /// </summary>
            /// <param name="pathFilePlist">Duong dan den file info.plist vua giai nen</param>
            /// <param name="forlderSavePlist">Duong dan luu tru lai file .plist da dc giai ma. </param>
            public static string ConvertSavePlist(string pathFilePlist, string forlderSavePlist)
            {
                PListRoot root = PListRoot.Load(pathFilePlist);
                string result = forlderSavePlist + "info.plist";
                using (MemoryStream memStream = new MemoryStream())
                {
                    root.Save(result, PListFormat.Xml);
                }

                return result;
            }

            public static string ConvertSavePlist(string pathFilePlist, string forlderSavePlist, string fileName)
            {
                PListRoot root = PListRoot.Load(pathFilePlist);
                string result = forlderSavePlist + fileName + ".plist";
                using (MemoryStream memStream = new MemoryStream())
                {
                    root.Save(result, PListFormat.Xml);
                }

                return result;
            }

            public static string ConvertSavePlist(string pathFileConvert, string forlderSavePlist, string fileName, out string embedResult)
            {
                string plistConvert = pathFileConvert + "\\info.plist";
                string embedConvert = pathFileConvert + "\\embedded.mobileprovision";
                PListRoot rootPlist = PListRoot.Load(plistConvert);
                PListRoot rootEmbed = PListRoot.Load(embedConvert);

                string result = forlderSavePlist + fileName + ".plist";
                embedResult = forlderSavePlist + "embedded.mobileprovision";
                using (MemoryStream memStream = new MemoryStream())
                {
                    rootPlist.Save(result, PListFormat.Xml);
                }

                using (MemoryStream memStream = new MemoryStream())
                {
                    rootEmbed.Save(embedResult, PListFormat.Xml);
                }

                return result;
            }


            /// <summary>
            /// Tra ve gia tri cua tung item trong file plist
            /// </summary>
            /// <param name="key"></param>
            /// <param name="dict"></param>
            /// <returns></returns>
            private static string ReturnValueItemPlist(string key, Dictionary<string,string> dict)
            {
                string value = "";
                if (dict.ContainsKey(key))
                {
                    value = dict[key];
                }

                return value;
            }

            /// <summary>
            /// Luu lai file .plist sau khi da giai ma thanh XML
            /// </summary>
            /// <param name="pathFilePlist">Duong dan den file .plist da giai ma</param>
            /// <param name="folderSavePlist">Duong dan folder luu lai file plist de cac thiet bi doc dc</param>
            /// <param name="urlInstall">Duong dan file cai</param>
            /// <param name="fileSize">Dung luong file</param>
            /// <param name="filename">Ten file dc chuyen doi thanh Guid</param>
            /// <param name="folderfile">Thu muc file cai</param>
            /// <param name="AppMode">Loai ung dung tuy theo nhan vien dc su dung</param>
            /// <param name="AppDesc">Mo ta cuu ung dung</param>
            /// <param name="isPublished"></param>
            /// <param name="AppJB">Ung dung Jailbreak</param>
            /// <param name="ImageUrl"></param>
            /// <param name="expirationDate"></param>
            public static void InsertAppList(string pathFilePlist, string folderSavePlist, string urlInstall, int fileSize, string filename, 
                                string folderfile, int AppMode, string AppDesc, bool isPublished, bool AppJB, string ImageUrl, DateTime expirationDate)
            {
                BO.PList pl = new BO.PList();
                pl.Load(pathFilePlist);

                string value = "";
                string key = "";
                List<dynamic> list = new List<dynamic>();
                Dictionary<string, string> dict = new Dictionary<string, string>();
                for (int i = 0; i < plistKey.Length; i++)
                {
                    value = "";
                    key = plistKey[i];
                    if (pl.ContainsKey(key))
                    {
                        if (key == "UIDeviceFamily" || key == "CFBundleSupportedPlatforms")
                        {
                            list = pl[key];

                            for (int j = 0; j < list.Count; j++)
                            {
                                if (j < list.Count - 1)
                                    value += list[j] + ",";
                                else
                                    value += list[j];
                            }

                        }
                        else
                        {
                            value = pl[key];
                        }
                    }

                    dict.Add(key, value);
                }

                string value_CFBundleIdentifier = dict["CFBundleIdentifier"];
                string value_CFBundleVersion = dict["CFBundleVersion"];
                string value_CFBundleDisplayName = dict["CFBundleDisplayName"];
                string value_CFBundleName = dict["CFBundleName"];
                string value_MinimumOSVersion = dict["MinimumOSVersion"];
                string value_CFBundleSupportedPlatforms = dict["CFBundleSupportedPlatforms"];
                string value_CFBundleSignature = dict["CFBundleSignature"];
                string value_BuildTime = dict["BuildTime"];
                string value_DTPlatformName = dict["DTPlatformName"];
                string value_DTPlatformVersion = dict["DTPlatformVersion"];
                string value_UIDeviceFamily = dict["UIDeviceFamily"];
                string value_ExpirationDate = GetExpirationDate(pathFilePlist); ;
                string appPlistContent = "";

                string value_AppKey = "";
                string value_AppIcon = ImageUrl;                
                
                string value_DisplayName = "", value_Name = "";

                int value_AppSize = fileSize;
               


                value_Name = value_CFBundleName;
                value_DisplayName = value_CFBundleDisplayName;             
                
                value_AppKey = Guid.NewGuid().ToString();
                if (value_CFBundleIdentifier.Length > 0 && value_CFBundleVersion.Length > 0)
                {
                    
                    string folderSave = folderSavePlist;
                    if (!Directory.Exists(folderSave))
                        Directory.CreateDirectory(folderSave);


                    StringBuilder builder = Manifest.BuilManifest(value_DisplayName, value_CFBundleIdentifier, value_CFBundleVersion, Common.UrlInstall + urlInstall, Common.UrlInstall + value_AppIcon);

                    appPlistContent = Manifest.BuildPlistContent(Common.UrlInstall + urlInstall, Common.UrlInstall + value_AppIcon, value_CFBundleIdentifier, value_CFBundleVersion, value_CFBundleDisplayName);         

                    FileStream fileStream = new FileStream(folderSave + "\\" + filename + ".plist", FileMode.Create, FileAccess.ReadWrite);
                    byte[] buffer = System.Text.Encoding.UTF8.GetBytes(builder.ToString());
                    fileStream.Write(buffer, 0, buffer.Length);
                    fileStream.Close();
                    string strAppPlistPath = folderInfo.Replace("\\", "/") + folderfile + "/" + filename + ".plist";
                    
                    if (value_BuildTime == "")
                        value_BuildTime = DateTime.Now.ToString();

                    if (value_DisplayName == "")
                        value_DisplayName = value_Name;

                    BO.Data.InsertAppPlist(value_AppKey, value_Name, value_DisplayName, value_CFBundleVersion, value_CFBundleIdentifier,
                                            value_UIDeviceFamily, value_MinimumOSVersion, value_AppSize,
                                            strAppPlistPath.ToLower(), urlInstall.ToLower(), value_CFBundleSignature, value_AppIcon,
                                            Convert.ToDateTime(value_BuildTime), AppMode, AppDesc, isPublished,
                                            AppJB, value_DTPlatformVersion, value_DTPlatformName, expirationDate, appPlistContent);
                }
                
            }
            
            private static string GetExpirationDate(string pathFileEmbed)
            {
                BO.Embed pl = new BO.Embed();
                pl.Load(pathFileEmbed);

                string value = "";
                string key = expirationDate;
                List<dynamic> list = new List<dynamic>();
                if(pl.ContainsKey(key))
                {
                    value = pl[key];
                }

                return value;
                
                /*
                for (int i = 0; i < plistKey.Length; i++)
                {
                    value = "";
                    key = plistKey[i];
                    if (pl.ContainsKey(key))
                    {
                        if (key == "UIDeviceFamily" || key == "CFBundleSupportedPlatforms")
                        {
                            list = pl[key];

                            for (int j = 0; j < list.Count; j++)
                            {
                                if (j < list.Count - 1)
                                    value += list[j] + ",";
                                else
                                    value += list[j];
                            }

                        }
                        else
                        {
                            value = pl[key];
                        }
                    }

                    dict.Add(key, value);
                }
                */
            }

            /// <summary>
            /// Save lai thanh file plist de device doc dc.
            /// </summary>
            /// <param name="folder"></param>
            /// <param name="title"></param>
            /// <param name="content"></param>
            private static void SaveFileInfo(string folder, string title, string content)
            {
                FileStream fileStream = new FileStream(folder + title.Substring(0, title.IndexOf(".")) + "_org" + ".plist", FileMode.Create, FileAccess.ReadWrite);
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(content);
                fileStream.Write(buffer, 0, buffer.Length);
                fileStream.Close();
            }

            
        }

        
        public static bool CheckMenuID(string[] arr, string strCom)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] == strCom)
                    return true;
            }

            return false;
        }
        public static string ReturnAppSize(string appsize)
        {
            string value = "";
            double fileSize = Convert.ToDouble(appsize);
            double fileSizeTemp = 0;
            if (fileSize < 1024)
            {
                value = fileSize + " Byte";
            }
            else
            {
                fileSizeTemp = fileSize / 1024;
                if (fileSizeTemp < 1024)
                {
                    value = fileSizeTemp.ToString("#,##0") + " Kb";
                }
                else
                {
                    fileSizeTemp = (fileSize / 1024) / 1024;
                    if (fileSizeTemp < 1024)
                    {
                        value = fileSizeTemp.ToString("#,##0");
                    }
                    else
                    {
                        fileSizeTemp = ((fileSize / 1024) / 1024) / 1024;
                        value = fileSizeTemp.ToString("#,##0") + " Gb";
                    }
                }
            }

            return value;
        }

        public static string CreateMD5Hash(string input)
        {
            // Use input string to calculate MD5 hash
            MD5 md5 = System.Security.Cryptography.MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = md5.ComputeHash(inputBytes);

            // Convert the byte array to hexadecimal string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));

            }
            return sb.ToString();
        }

        public static string MD5Hash(string username, string password)
        {
            string sHashWithSalt = password + username;
            // convert this merged value to a byte array
            byte[] saltedHashBytes = Encoding.UTF8.GetBytes(sHashWithSalt);
            // use hash algorithm to compute the hash
            System.Security.Cryptography.HashAlgorithm algorithm = new System.Security.Cryptography.SHA256Managed();
            // convert merged bytes to a hash as byte array
            byte[] hash = algorithm.ComputeHash(saltedHashBytes);
            // return the has as a base 64 encoded string
            string base64 = Convert.ToBase64String(hash);

            string result = CreateMD5Hash(base64);
            return result;
        }

        

        public static string GetPathFileInfoPlist(string ipaFile)
        {

            System.ZLib.Zip.ZipFile zipFile = new System.ZLib.Zip.ZipFile(ipaFile);

            string path = "";
            string zipName = "";
            string[] arr;
            string namePlist = "";
            for (int i = 0; i < zipFile.Count; i++)
            {
                zipName = zipFile[i].Name.ToLower();
                arr = zipName.Split("/".ToCharArray());
                if (arr.Length <= 3)
                {
                    if (zipName.IndexOf(@"info.plist") > 0)
                    {
                        namePlist = arr[arr.Length - 1];
                        if (namePlist == "info.plist")
                        {
                            path = zipFile[i].Name;
                            break;
                        }
                        
                    }
                }
            }
            return path;
        }
        
        public static bool ExtractIPA(string pathToIpa, string saveFolderPath)
        {
            bool value = false;
            string ipaPath = pathToIpa;
            string savePath = saveFolderPath;

            try
            {
                
                if (!String.IsNullOrEmpty(ipaPath) &&
                   !String.IsNullOrEmpty(saveFolderPath))
                {
                    try
                    {
                     
                        
                        FastZip fz = new FastZip();
                        fz.ExtractZip(ipaPath, saveFolderPath, "Info.plist");                       
                        
                        fz.ExtractZip(ipaPath, saveFolderPath, "embedded.mobileprovision");     
                        
                        value= true;                 
                    }
                    catch (Exception ex)
                    {
                    
                        value = false;
                    }
                }
                else
                {
              
                    value=false;
                }
            }
            catch (Exception ex)
            {
              
                value=false;
            }

            return value;
        }

        public static bool CheckInt(string Value)
        {
            if (Value == String.Empty)
                return false;
            if (Value == null)
                return false;
            foreach (char c in Value)
            {
                int i;

                i = Convert.ToInt16(c);

                if ((i > 57) || (i < 48))
                    return false;
            }
            return true;
        }

        public class SpecialCharacters
        {
            ////private static string[] SC = new string[] { "$", "^", "{", "}", "[", "]", "(", "|", ")", "*", "+", "?", "\\", "@", "!", "/", ",", "<", ">", ":", ";", "\"", "=", "-", "'", "~", "`" };

            private static string[] SC = new string[] { "?","&","%" };

            /// <summary>
            /// Check xem string co ky tu dac biet hay ko ? True: Ko co; False : co
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static bool Check(string input)
            {
                int countSC = SC.Length;

                for (int i = 0; i < countSC; i++)
                {
                    if (input.IndexOf(SC[i]) > -1)
                    {
                        return false;
                    }
                }
                return true;
            }
        }

        public class Unicode
        {
            public const string uniChars =
           "àáảãạâầấẩẫậăằắẳẵặèéẻẽẹêềếểễệđìíỉĩịòóỏõọôồốổỗộơờớởỡợùúủũụưừứửữựỳýỷỹỵÀÁẢÃẠÂẦẤẨẪẬĂẰẮẲẴẶÈÉẺẼẸÊỀẾỂỄỆĐÌÍỈĨỊÒÓỎÕỌÔỒỐỔỖỘƠỜỚỞỠỢÙÚỦŨỤƯỪỨỬỮỰỲÝỶỸỴÂĂĐÔƠƯ";

            public const string KoDauChars =
                "aaaaaaaaaaaaaaaaaeeeeeeeeeeediiiiiooooooooooooooooouuuuuuuuuuuyyyyyAAAAAAAAAAAAAAAAAEEEEEEEEEEEDIIIOOOOOOOOOOOOOOOOOOOUUUUUUUUUUUYYYYYAADOOU";

            public static string UnicodeToKoDau(string s)
            {
                string retVal = String.Empty;
                int pos;
                for (int i = 0; i < s.Length; i++)
                {
                    pos = uniChars.IndexOf(s[i].ToString());
                    if (pos >= 0)
                        retVal += KoDauChars[pos];
                    else
                        retVal += s[i];
                }
                return retVal;
            }

            /// <summary>
            /// Kiem tra chuoi co Unicode hay ko ? Neu co tra ve true, ngươc lai False
            /// </summary>
            /// <param name="s"></param>
            /// <returns></returns>
            public static bool CheckUnicode(string s)
            {
                int pos;
                for (int i = 0; i < s.Length; i++)
                {
                    pos = uniChars.IndexOf(s[i].ToString());
                    if (pos >= 0)
                        return true;                    
                }

                return false;
            }
        }
    }
}
